//#![feature(extend_one)] // nightly 必须放在源代码开头
use function_name::named;
use macro_colors::*;
// 引用的是 rust_test.lib 中的 common; common 不是当前 exe 的子模块
use my_commons::*;
use my_proc_macro::*;

#[mydbginfo]
pub fn te1() {
    // 通过 \ + 字符的十六进制表示，转义输出一个字符
    let byte_escape = "I'm writing \x52\x75\x73\x74!";
    println!("What are you doing\x3F (\\x3F means ?) {}", byte_escape);

    // \u 可以输出一个 unicode 字符
    let unicode_codepoint = "\u{211D}";
    let character_name = "\"DOUBLE-STRUCK CAPITAL R\"";

    println!(
        "Unicode character {} (U+211D) is called {}",
        unicode_codepoint, character_name
    );

    // 换行了也会保持之前的字符串格式
    // 使用\忽略换行符
    let long_string = "String literals
                        can span multiple lines.
                        The linebreak and indentation here ->\
                        <- can be escaped too!";
    println!("{}", long_string);
}

#[mydbginfo]
pub fn te2() {
    println!("{}", "hello \\x52\\x75\\x73\\x74");
    let raw_str = r"Escapes don't work here: \x3F \u{211D}";
    println!("{}", raw_str);

    // 如果字符串包含双引号，可以在开头和结尾加 #
    let quotes = r#"And then I said: "There is no escape!""#;
    println!("{}", quotes);

    // 如果字符串中包含 # 号，可以在开头和结尾加多个 # 号，最多加255个，只需保证与字符串中连续 # 号的个数不超过开头和结尾的 # 号的个数即可
    let longer_delimiter = r###"A string with "# in it. And even "##!"###;
    println!("{}", longer_delimiter);

    let qq = r"have # signs ## and ###, and ####";
    println!("{}", qq);
}

#[mydbginfo]
pub fn te3() {
    // str 就是 ptr + len; ptr指向可变(长度内容可变); ptr 不变时, len 可以缩短.
    // &str 就是 ptr + len 并且内容长度不可变.

    // F0 9F 97 BB E2 88 88 F0 9F 8C 8F
    // 字符串 literal 只能是 &str, 不能是 &mut str,
    // 短字符串直接分配在 栈上
    let mut s = String::from("🗻∈🌏");
    println!("s: {}", s);
    unsafe {
        let bytes = s.as_bytes_mut();
        bytes[0] = 0xF0;
        bytes[1] = 0x9F;
        bytes[2] = 0x8D;
        bytes[3] = 0x94;
    }
    assert_eq!("🍔∈🌏", s);
    println!("s => {}", s);
}

#[mydbginfo]
pub fn te4() {
    let mut s = String::from("🗻∈🌏");
    println!("s: {}", s);
    let b = "bbb";
    s.extend(b.chars());
    unsafe {
        let bytes = s.as_bytes_mut();
        // 如果不 extend, 会超过 bytes 边界 panick
        if true {
            bytes[11] = 0xE4;
            bytes[12] = 0xB8;
            bytes[13] = 0xAD;
        }

        println!("{:?}", bytes);
    }
    println!("s => {}", s);
}
